<template>
  <n-card title="商品规格">
    <template v-if="!prodId" #header-extra>
      <n-popover trigger="click">
        <template #trigger>
          <n-button size="small" type="primary" :disabled="skuFlg === 0">新增规格</n-button>
        </template>
        <n-space align="center">
          <n-input v-model:value="addAttrName" placeholder="请输入规格名称" />
          <n-button type="primary" text @click="handleAddAttr">确定</n-button>
        </n-space>
      </n-popover>
    </template>
    <div v-if="skuFlg === 0" style="width: 100%">
      <n-table :single-line="false" size="small" style="width: 100%">
        <thead>
          <tr>
            <th style="width: 50px">图片</th>
            <th>名称</th>
            <th>货号</th>
            <th>条形码</th>
            <th style="width: 80px">库存</th>
            <th style="width: 120px">价格</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="sku in prodSkuList" :key="sku.key">
            <td>
              <SelectImgWrap v-model:value="sku.picUrl" file-tp-cd="PROD_SKU_PIC" size="48px" />
            </td>
            <td><n-input v-model:value="sku.skuNm" @update:value="handleUpdateSkuList" /></td>
            <td><n-input v-model:value="sku.skuNo" @update:value="handleUpdateSkuList" /></td>
            <td><n-input v-model:value="sku.barCd" @update:value="handleUpdateSkuList" /></td>
            <td><n-input-number v-model:value="sku.stock" :show-button="false" @update:value="handleUpdateSkuList" /></td>
            <td><n-input-number v-model:value="sku.costPrc" :show-button="false" :precision="2" @update:value="handleUpdateSkuList" /></td>
          </tr>
        </tbody>
      </n-table>
    </div>
    <n-grid v-else :cols="2" :x-gap="24">
      <template v-if="!prodId">
        <n-form-item-gi :span="2" v-for="attr in prodSkuAttrList" :label="attr.attrNm" :key="attr.attrCd">
          <n-checkbox-group v-model:value="attr.valList" @update:value="generateProdSku">
            <n-flex align="center">
              <n-tag v-for="item in attr.optList" :key="item.optVal" type="primary">
                <n-flex align="center">
                  <n-checkbox :value="item.optVal" />
                  <span>{{ item.optLab }}</span>
                  <!-- 删除规格选项 -->
                  <n-button text size="tiny" type="error" @click="handleDelSkuAttrOpt(attr, item)">
                    <template #icon>
                      <n-icon size="14">
                        <CloseOutlined />
                      </n-icon>
                    </template>
                  </n-button>
                </n-flex>
              </n-tag>
              <!-- 新增规格选项 -->
              <n-popover trigger="click">
                <template #trigger>
                  <n-button type="primary" text>
                    <template #icon>
                      <n-icon>
                        <PlusOutlined />
                      </n-icon>
                    </template>
                  </n-button>
                </template>
                <n-space align="center">
                  <n-input v-model:value="attr.addOptLab" placeholder="请输入名称" />
                  <n-button type="primary" text @click="handleAddSkuAttrOpt(attr)">确认</n-button>
                </n-space>
              </n-popover>
              <!-- 删除规格 -->
              <n-popconfirm @positive-click="handleDelSkuAttr(attr)">
                <template #trigger>
                  <n-button type="error" text>
                    <template #icon>
                      <n-icon>
                        <DeleteOutlined />
                      </n-icon>
                    </template>
                  </n-button>
                </template>
                确认删除“{{ attr.attrNm }}”？
              </n-popconfirm>
            </n-flex>
          </n-checkbox-group>
        </n-form-item-gi>
      </template>
      <n-form-item-gi :span="2" :show-feedback="false" :show-label="false">
        <div style="width: 100%">
          <n-table :single-line="false" size="small" style="width: 100%">
            <thead>
              <tr>
                <th style="width: 25px; text-align: center">默认</th>
                <th style="width: 50px">图片</th>
                <th>规格</th>
                <th>名称</th>
                <th>货号</th>
                <th>条形码</th>
                <th style="width: 120px">
                  <n-space align="center">
                    <span>库存</span>
                    <n-popover trigger="click">
                      <template #trigger>
                        <n-button type="primary" text>批量设置</n-button>
                      </template>
                      <n-space align="center">
                        <n-input-number v-model:value="batchStock" placeholder="请输入库存" />
                        <n-button type="primary" text @click="handleBatchStock">设置</n-button>
                      </n-space>
                    </n-popover>
                  </n-space>
                </th>
                <th style="width: 120px">
                  <n-space align="center">
                    <span>价格</span>
                    <n-popover trigger="click">
                      <template #trigger>
                        <n-button type="primary" text>批量设置</n-button>
                      </template>
                      <n-space align="center">
                        <n-input-number v-model:value="batchCostPrc" :precision="2" placeholder="请输入价格" />
                        <n-button type="primary" text @click="handleBatchCostPrc">设置</n-button>
                      </n-space>
                    </n-popover>
                  </n-space>
                </th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="sku in prodSkuList" :key="sku.key">
                <td style="text-align: center"><n-checkbox :checked="sku.dfltFlg === 1" @update:checked="handleDfltSkuChecked(sku)" /></td>
                <td>
                  <SelectImgWrap v-model:value="sku.picUrl" file-tp-cd="PROD_SKU_PIC" size="48px" />
                </td>
                <td>{{ sku.attrGroupNm }}</td>
                <td><n-input v-model:value="sku.skuNm" @update:value="handleUpdateSkuList" /></td>
                <td><n-input v-model:value="sku.skuNo" @update:value="handleUpdateSkuList" /></td>
                <td><n-input v-model:value="sku.barCd" @update:value="handleUpdateSkuList" /></td>
                <td><n-input-number v-model:value="sku.stock" :show-button="false" @update:value="handleUpdateSkuList" /></td>
                <td><n-input-number v-model:value="sku.costPrc" :show-button="false" :precision="2" @update:value="handleUpdateSkuList" /></td>
              </tr>
            </tbody>
          </n-table>
        </div>
      </n-form-item-gi>
    </n-grid>
  </n-card>
</template>
<script setup lang="ts">
import { ref, watch, toRaw } from 'vue';
import { PlusOutlined, DeleteOutlined, CloseOutlined } from '@vicons/antd';
import { SelectImgWrap } from '@/components/SelectMediaWrap';
import { DataTpEnum } from '@/modules/bmppd/enums/DataTpEnum';
import { ProdSku } from './formDataClass';
import { ProdTpAttr, ProdTpAttrOpt } from './attrDataClass';

defineOptions({
  name: 'ProdSkuCard'
});

class ProdAttrItem extends ProdTpAttr {
  valList: string[] = []; //枚举多选值储存
  addOptLab = ''; //枚举手动新增值存储
}

class CheckedOpt extends ProdTpAttrOpt {
  attrCd: string | null = null;
  attrNm = '';
  dataTpCd: DataTpEnum = DataTpEnum.TEXT;
}

interface ISkuAttrJson {
  attrCd: string | null;
  attrNm: string;
  dataTpCd: DataTpEnum;
  optVal: string | null;
  optLab: string;
}

const props = withDefaults(
  defineProps<{
    prodId: string;
    prodNm: string;
    skuFlg: number;
    cvrUrl: string;
    skuAttrList: ProdTpAttr[];
    skuList: ProdSku[];
    createAttrCd: () => string;
  }>(),
  {
    prodId: '',
    prodNm: '',
    skuFlg: 0,
    cvrUrl: '',
    attrList: () => [],
    skuList: () => []
  }
);

const emits = defineEmits<{
  (e: 'update:skuAttrList', list: ProdTpAttr[]): void;
  (e: 'update:skuList', list: ProdSku[]): void;
}>();

defineExpose({ cleanAllOptValList });

const prodSkuAttrList = ref<ProdAttrItem[]>([]);

const prodSkuList = ref<ProdSku[]>([]);

const addAttrName = ref<string>('');
const batchStock = ref<number>(0);
const batchCostPrc = ref<number>(0);

watch(
  () => props.skuList,
  (list) => {
    prodSkuList.value = list.map((item) => {
      let attrGroupNm = '';
      try {
        const skuAttrList: ISkuAttrJson[] = JSON.parse(item.skuAttrList);
        const attrGroupArr = skuAttrList.map((attr) => attr.attrNm + ':' + attr.optLab);
        attrGroupNm = attrGroupArr.join(' ');
        // eslint-disable-next-line no-empty
      } catch (e) {}
      return { ...item, attrGroupNm };
    });
  },
  { deep: true }
);

watch(
  () => props.skuAttrList,
  (attrList) => {
    prodSkuAttrList.value = attrList.map((item) => {
      let valList: string[] = [];
      // if (item.dataTpCd === DataTpEnum.ENUM && item.multFlg === 1) {
      //   valList = item.val ? item.val.split(',') : [];
      // }
      valList = item.val ? item.val.split(',') : [];
      return { ...item, valList, addOptLab: '' };
    });
  },
  { deep: true }
);

//新增规格项
function handleAddAttr() {
  const attrNmArr = prodSkuAttrList.value.map((item) => item.attrNm);
  if (attrNmArr.includes(addAttrName.value)) {
    window.$message.error('规格名称重复');
    return;
  }
  const newAttr = new ProdAttrItem();
  newAttr.attrCd = props.createAttrCd();
  newAttr.attrNm = addAttrName.value;
  newAttr.skuFlg = 1;
  newAttr.dataTpCd = DataTpEnum.ENUM;
  newAttr.multFlg = 1;
  prodSkuAttrList.value.push(newAttr);
  addAttrName.value = '';
  handleUpdateAttrList();
}
//删除规格项
function handleDelSkuAttr(attr: ProdAttrItem) {
  const index = prodSkuAttrList.value.findIndex((item) => attr.attrCd === item.attrCd);
  if (index > -1) {
    prodSkuAttrList.value.splice(index, 1);
  }
  if (attr.valList.length > 0) {
    generateProdSku();
  } else {
    handleUpdateAttrList();
  }
}

//新增SKU规格选项
function handleAddSkuAttrOpt(attr: ProdAttrItem) {
  const optNmArr = attr.optList.map((item) => item.optLab);
  if (optNmArr.includes(attr.addOptLab)) {
    window.$message.error('规格选项名称重复');
    return;
  }
  const newOpt = new ProdTpAttrOpt();
  newOpt.optVal = createOptVal(attr);
  newOpt.optLab = attr.addOptLab;
  attr.optList.push(newOpt);
  attr.addOptLab = '';
  handleUpdateAttrList();
}

//删除SKU规格选项
function handleDelSkuAttrOpt(attr: ProdAttrItem, item: ProdTpAttrOpt) {
  const index = attr.optList.findIndex((optItem) => optItem.optVal === item.optVal);
  if (index > -1) {
    attr.optList.splice(index, 1);
  }
  const optValIndex = attr.valList.indexOf(item.optVal);
  if (optValIndex > -1) {
    attr.valList.splice(optValIndex, 1);
    generateProdSku();
  } else {
    handleUpdateAttrList();
  }
}
//生成新的optVal
function createOptVal(attr: ProdAttrItem) {
  const optValArr = attr.optList.map((item) => Number(item.optVal)).filter((item) => !isNaN(item));
  if (optValArr.length < 1) {
    return '01';
  } else {
    return String(Math.max(...optValArr) + 1).padStart(2, '0');
  }
}

function generateProdSku() {
  handleUpdateAttrList();
  const optGroupList: CheckedOpt[][] = [];
  for (const attr of prodSkuAttrList.value) {
    const { attrCd, attrNm, dataTpCd } = attr;
    if (attr.valList.length > 0 && attr.optList.length > 0) {
      const optList: CheckedOpt[] = [];
      for (const opt of attr.optList) {
        if (opt.optVal && attr.valList.includes(opt.optVal)) {
          optList.push({ attrCd, attrNm, dataTpCd, ...opt });
        }
      }
      if (optList.length > 0) {
        optGroupList.push(optList);
      }
    }
  }
  prodSkuList.value = [];
  if (optGroupList.length < 1) return;
  const skuGroupList = optGroupList.reduce<CheckedOpt[][]>(
    (pre, cur) => {
      const ret: CheckedOpt[][] = [];
      pre.forEach((group) => {
        cur.forEach((item) => {
          ret.push(group.concat([item]));
        });
      });
      return ret;
    },
    [[]]
  );
  for (const attrOptList of skuGroupList) {
    const skuCdArr: string[] = [];
    const attrNmArr: string[] = [];
    const skuAttrList: ISkuAttrJson[] = [];
    for (const attrOpt of attrOptList) {
      const { attrCd, attrNm, dataTpCd, optVal, optLab } = attrOpt;
      skuCdArr.push(attrOpt.attrCd + attrOpt.optVal);
      attrNmArr.push(attrOpt.attrNm + ':' + attrOpt.optLab);
      skuAttrList.push({ attrCd, attrNm, dataTpCd, optVal, optLab });
    }
    const skuCd = skuCdArr.sort().join('');
    const prodSku = new ProdSku();
    prodSku.skuCd = skuCd;
    prodSku.attrGroupNm = attrNmArr.join(' ');
    prodSku.skuNm = props.prodNm + ' ' + attrNmArr.join(' ');
    prodSku.skuAttrList = JSON.stringify(skuAttrList);
    prodSku.picUrl = props.cvrUrl;
    prodSkuList.value.push(prodSku);
  }
  handleUpdateSkuList();
}

function handleDfltSkuChecked(prodSku: ProdSku) {
  prodSkuList.value.forEach((sku) => {
    sku.dfltFlg = 0;
  });
  prodSku.dfltFlg = 1;
  handleUpdateSkuList();
}

function handleUpdateAttrList() {
  prodSkuAttrList.value.forEach((attr) => {
    // if (attr.dataTpCd === DataTpEnum.ENUM && attr.multFlg === 1) {
    //   attr.val = attr.valList.join(',');
    // }
    attr.val = attr.valList.join(',');
  });
  emits('update:skuAttrList', toRaw(prodSkuAttrList.value));
}
function handleUpdateSkuList() {
  emits('update:skuList', toRaw(prodSkuList.value));
}

//清空所有SKU规格已勾选选项，单/多规格切换时使用
function cleanAllOptValList() {
  prodSkuAttrList.value.forEach((item) => {
    item.valList = [];
  });
}

//SKU列表批量修改库存
function handleBatchStock() {
  prodSkuList.value.forEach((item) => {
    item.stock = batchStock.value;
  });
  batchStock.value = 0;
  handleUpdateSkuList();
}

//SKU列表批量修改成本价
function handleBatchCostPrc() {
  prodSkuList.value.forEach((item) => {
    item.costPrc = batchCostPrc.value;
  });
  batchCostPrc.value = 0;
  handleUpdateSkuList();
}
</script>

<style lang="scss" scoped></style>
